package com.ruoyi.cms.controller.admin;

import com.ruoyi.cms.common.BaseController;
import com.ruoyi.cms.domain.Theme;
import com.ruoyi.cms.domain.vo.TemplateVO;
import com.ruoyi.cms.exception.CmsException;
import com.ruoyi.cms.exception.TemplateNotFoundException;
import com.ruoyi.cms.exception.TemplatePermissionDeniedException;
import com.ruoyi.cms.service.ThemeService;
import com.ruoyi.cms.util.FileConfiguration;
import com.ruoyi.cms.util.StateCodeEnum;
import com.ruoyi.common.core.domain.R;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 模板管理
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/cms/templates")
public class TemplateController extends BaseController {
	@Autowired
	private FileConfiguration fileConfiguration;
	@Autowired
	private ThemeService themeService;

	@RequestMapping("index")
	public R<List<Map<String,String>>> toIndex() {
		Theme currentTheme = themeService.getCurrentTheme();
		String resourceDir = fileConfiguration.getResourceDir();
		String themePath = resourceDir + File.separator + "templates" + File.separator + currentTheme.getThemePath() + File.separator;
		themePath = themePath.replaceAll("\\*", "/");

		File themeDir = new File(themePath);
		File[] listFiles = themeDir.listFiles();

		List<Map<String,String>> list = new LinkedList<Map<String,String>>();
		for (File file : listFiles) {
			Map<String,String> map = new HashMap<String,String>();
			String fileName = file.getName();
			map.put("path", file.getParent());
			map.put("fileName", fileName);
            map.put("file", fileName);
			String extName = fileName.substring(fileName.lastIndexOf(".") == -1 ? 0 : fileName.lastIndexOf("."));
			map.put("extName", extName);
			if(file.isDirectory()) {
				map.put("type", "directory");
				list.add(0, map);
			}else if(file.isFile()) {
				map.put("type", "file");
				list.add(map);
			}
		}
		return R.ok(list);
	}

	@PostMapping("toView")
	public R<List<Map<String,String>>> toView(@RequestBody TemplateVO param) throws IOException, CmsException {
		String themeDirPath = param.getPath() + File.separator + param.getFileName() + File.separator;
		File themeDirPathFile = new File(themeDirPath);

		/**
		 * 查询当前模版目录，判断是否为模版目录，如不是，则报错
		 */
		Theme currentTheme = themeService.getCurrentTheme();
		String resourceDir = fileConfiguration.getResourceDir();
		String themePath = resourceDir + File.separator + "templates" + File.separator + currentTheme.getThemePath() + File.separator;
		themePath = themePath.replaceAll("\\*", "/");
		File themeDir = new File(themePath);
		if(!themeDirPathFile.getCanonicalPath().startsWith(themeDir.getCanonicalPath())) {
			throw new TemplatePermissionDeniedException(StateCodeEnum.HTTP_FORBIDDEN.getCode(), StateCodeEnum.HTTP_FORBIDDEN.getDescription(), "您没有操作权限！");
		}

		File[] listFiles = themeDirPathFile.listFiles();
		List<Map<String,String>> list = new LinkedList<Map<String,String>>();
		for (File file : listFiles) {
			Map<String,String> map = new HashMap<String,String>();
			String fn = file.getName();
			map.put("path", file.getParent());
			map.put("fileName", fn);
            map.put("file", fn);
			String extName = fn.substring(fn.lastIndexOf(".") == -1 ? 0 : fn.lastIndexOf("."));
			map.put("extName", extName);
			if(file.isDirectory()) {
				map.put("type", "directory");
				list.add(0, map);
			}else if(file.isFile()) {
				map.put("type", "file");
				list.add(map);
			}
		}
		return R.ok(list);
	}

	@PostMapping("toEdit")
	public R<Map<String, String>> toEdit(@RequestBody TemplateVO param) throws IOException, CmsException {
		Map<String, String> result = new HashMap<>();
		String fileName = param.getPath() + File.separator + param.getFileName();
		File templateFile = new File(fileName);
		/**
		 * 查询当前模版目录，判断是否为模版目录，如不是，则报错
		 */
		Theme currentTheme = themeService.getCurrentTheme();
		String resourceDir = fileConfiguration.getResourceDir();
		String themePath = resourceDir + File.separator + "templates" + File.separator + currentTheme.getThemePath() + File.separator;
		themePath = themePath.replaceAll("\\*", "/");
		File themeDir = new File(themePath);
		if(!templateFile.getCanonicalPath().startsWith(themeDir.getCanonicalPath())) {
			throw new TemplatePermissionDeniedException(StateCodeEnum.HTTP_FORBIDDEN.getCode(), StateCodeEnum.HTTP_FORBIDDEN.getDescription(), "您没有操作权限！");
		}
		String content = FileUtils.readFileToString(templateFile, "UTF-8");
        result.put("content", content);
        result.put("path", param.getPath());
        result.put("fileName", param.getFile());
        result.put("file", param.getFile());
		return R.ok(result);
	}

	@PostMapping("save")
	public R<String> save(@RequestBody TemplateVO template) throws IOException, CmsException {
		String fileName = template.getPath() + File.separator + template.getFileName();
		File templateFile = new File(fileName);
		/**
		 * 查询当前模版目录，判断是否为模版目录，如不是，则报错
		 */
		Theme currentTheme = themeService.getCurrentTheme();
		String resourceDir = fileConfiguration.getResourceDir();
		String themePath = resourceDir + File.separator + "templates" + File.separator + currentTheme.getThemePath() + File.separator;
		themePath = themePath.replaceAll("\\*", "/");
		File themeDir = new File(themePath);
		// 检查当前编辑文件是否有权限
		if(!templateFile.getCanonicalPath().startsWith(themeDir.getCanonicalPath())) {
			throw new TemplatePermissionDeniedException(StateCodeEnum.HTTP_FORBIDDEN.getCode(), StateCodeEnum.HTTP_FORBIDDEN.getDescription(), "您没有操作权限！");
		}
		if(!templateFile.exists()) {
			throw new TemplateNotFoundException(StateCodeEnum.HTTP_NOTFOUND.getCode(), StateCodeEnum.HTTP_NOTFOUND.getDescription(), "模板文件不存在！");
		}

		String filePath = template.getPath() + File.separator + template.getFile();
		filePath = filePath.replaceAll("\\*", "/");
		File file = new File(filePath);
		FileUtils.writeStringToFile(file, template.getContent(), "UTF-8");
		return R.ok();
	}

}
